/*
 * 代号：凤凰
 * http://www.jphenix.org
 * 2014-06-03
 * V4.0
 */
package com.jphenix.driver.internationalization;

import com.jphenix.driver.threadpool.ThreadSession;
import com.jphenix.kernel.objectloader.instanceb.BaseBean;
import com.jphenix.share.lang.SString;
import com.jphenix.share.util.SFilesUtil;
import com.jphenix.standard.docs.ClassInfo;
import com.jphenix.standard.internationalization.ILanguage;

import java.io.InputStream;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Properties;

/**
 * 语言信息对象
 * 
 * 规则：语言配置文件需要放到使用类的同级文件夹中。
 * 文件名为：类名_语言代码.properties
 * 文件内容采用UTF-8格式
 * 
 * @author 刘虻
 * 2010-2-2 下午01:18:47
 */
@ClassInfo({"2014-06-03 17:27","语言信息对象"})
public class Language extends BaseBean implements ILanguage {

	protected URL resourceFileURL  = null; //资源文件路径
	protected String fileNameHead = null; //资源文件名前缀
	protected String defaultLanguageCode = null; //默认语言代码
	protected HashMap<String,Properties> resMap = new HashMap<String,Properties>(); //资源对象容器
	protected Properties resourceProperties = null; //资源文件对象
	protected HashMap<String,String> codeMap = null; //语言代码对照容器
	
	/**
	 * 构造函数
	 * @author 刘虻
	 */
	public Language(
			URL resourceFileURL
			,String fileNameHead
			,String defaultLanguageCode
			,HashMap<String,String> codeMap) {
		super();
		this.resourceFileURL = resourceFileURL;
		this.fileNameHead = fileNameHead;
		this.defaultLanguageCode = defaultLanguageCode;
		this.codeMap = codeMap;
	}
	
	/**
	 * 获取有效的配置文件处理类
	 * 刘虻
	 * 2013-4-12 下午2:01:30
	 * @param code 语言代码
	 * @return 配置信息文件
	 */
	protected Properties getProperties(String code) {
		if(code==null || code.length()<1) {
			code = defaultLanguageCode;
		}
		if(code==null || code.length()<1) {
			return new Properties();
		}
		//从对照表中获取转译后的代码
		String oCode = SString.valueOf(codeMap.get(code.toUpperCase()));
		if(oCode.length()>0) {
			code = oCode;
		}
		//获取配置信息对象
		Properties prop = resMap.get(code);
		if(prop==null) {
			//初始化资源文件
			prop = new Properties();
			resMap.put(code,prop);
			//获取国际化文件读入流
			InputStream is = getResourceInputStreamByUrl(code);
			if(is!=null) {
				try {
					prop.load(is);
				}catch(Exception e) {
					//e.printStackTrace();
				}finally {
					try {
						is.close();
					}catch(Exception e) {}
				}
			}
		}
		return prop;
	}
	
	
	/**
	 * 通过类文件路径获取国际化文本输入流
	 * 刘虻
	 * 2013-4-9 下午4:23:46
	 * @param languageCode 语言代码
	 * @return 国际化文本输入流
	 */
	protected InputStream getResourceInputStreamByUrl(String languageCode) {
		//获取类根路径
		String basePath = resourceFileURL.toString();
		boolean isZip = false; //是否在压缩包内
		if(basePath.length()>0) {
			//检测字符串
			String checkStr = 
				basePath.substring(basePath.length()-4).toLowerCase();
			if(".jar".equals(checkStr) || ".zip".equals(checkStr)) {
				isZip = true;
			}
		}
		if(isZip) {
			//将file: 换成   zip:
			basePath = "zip"+basePath.substring(4)+"!/";
		}else {
			//去掉 file: 头
			basePath = basePath.substring(5);
		}
		//语言文件相对路径
		String subPath = fileNameHead+"_"+languageCode+".properties";
		if(SFilesUtil.isFileExist(subPath,basePath)) {
			try {
				return SFilesUtil.getFileInputStreamByUrl(subPath,basePath);
			}catch(Exception e) {
				e.printStackTrace();
			}
		}
		return null;
	}

	
	/**
	 * 覆盖方法
	 * 刘虻
	 * 2010-2-2 下午01:18:47
	 */
	@Override
    public String i(
			String languageCode
			,String contentKey
			,String defaultContent
			,String[] paraValues) {
		if(defaultContent==null) {
			defaultContent = contentKey;
			if(defaultContent==null) {
				defaultContent = "";
			}
		}
		if(contentKey==null || resourceFileURL==null) {
			return fixParameter(defaultContent,paraValues);
		}
		//构建返回值
		String reStr = null;
		try {
			reStr = new String(
					 SString.valueOf(
							 getProperties(languageCode)
							 	.get(contentKey))
							 		.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
         } catch (Exception e) {
        	 reStr = SString.valueOf(getProperties(languageCode).get(contentKey));
         }
         if(reStr.length()>0) {
        	 return fixParameter(reStr,paraValues);
         }
        return fixParameter(defaultContent,paraValues);
	}
	
	/**
	 * 覆盖方法
	 * 刘虻
	 * 2013-4-12 下午2:30:35
	 */
	@Override
    public String i(
			String contentKey
			,String defaultContent
			,String[] paraValues) {
		return i(
				ThreadSession.getString("locale")
				,contentKey,defaultContent,paraValues);
	}
	
	
	/**
	 * 处理字符串中的变量
	 * 将字符串中的<?>按照从前往后的顺序替换成参数值序列中的元素
	 * 刘虻
	 * 2010-6-2 下午05:08:16
	 * @param content 待处理字符串
	 * @param paraValues 参数值数组
	 * @return 处理后的字符串
	 */
	protected String fixParameter(String content,String[] paraValues) {
		if(paraValues==null) {
			return content;
		}
		if(content==null || content.length()<1) {
			return "";
		}
		//构建返回值
		StringBuffer reSbf = new StringBuffer();
		int lastPoint = 0; //上一个节点位置
		for(String value:paraValues) {
			//获取替换参数位置
			int point = content.indexOf("<?>",lastPoint);
			if(point<0) {
				reSbf.append(content.substring(lastPoint));
				break;
			}
			reSbf.append(content, lastPoint, point).append(SString.valueOf(value));
			lastPoint = point+3;
		}
		return reSbf.toString();
	}

	
	/**
	 * 设置资源文件对象
	 * 刘虻
	 * 2010-2-2 下午01:21:54
	 * @param is 资源文件对象输入流
	 */
	protected void setResourceInputStream(InputStream is) {
		if(is!=null) {
			resourceProperties = new Properties();
			try {
				resourceProperties.load(is);
			}catch(Exception e) {
				resourceProperties = null;
			}finally {
				try {
					is.close();
				}catch(Exception e) {}
			}
		}
	}
}
